<template>
  <div id="chat-view">
    <div class="chat-header">
      <h1>宁好办助手</h1>
      <h2>欢迎使用咸宁市智能惠企政策助手，随时为您供全市一站式的政策申报咨询服务</h2>
    </div>
    <div class="chat-body">
      <div class="chat-container">
        <div class="chat" ref="chatDiv"></div>
        <div class="input-container">
          <textarea v-model="message" @keyup.enter="send" cols="30" rows="2" placeholder="请输入您的消息..."></textarea>
          <button @click="send">发送</button>
        </div>
      </div>
      <div class="chat-faq">
        <h2>常见问题</h2>
        <ul>
          <li @click="sendFAQ('大学生就业补贴')">1. 大学生就业补贴</li>
          <li @click="sendFAQ('问题2')">2. 问题2</li>
          <li @click="sendFAQ('问题3')">3. 问题3</li>
          <!-- 添加更多问题 -->
        </ul>
      </div>
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref } from 'vue';
import { marked } from 'marked';
import { v4 as uuidv4 } from 'uuid';

const workspaceId = ref('deepseek-r1');
const threadId = ref(null);
const message = ref('');
const output = ref('');
const chatDiv = ref(null);
const renderer = new marked.Renderer();

onMounted(async () => {
  let currentThread = localStorage.getItem('current-thread');
  if (!currentThread) {
    currentThread = uuidv4(); // 生成新的 UUID
    await createThread(currentThread);
  }
  threadId.value = currentThread;
});

const sendFAQ = async (msg) => {
  message.value = msg;
  await send();
};

const send = async () => {
  const prompt = "假如你就是一位精通湖北省咸宁市惠企政策的客服人员，为用户提供全省一站式的政策申报、奖补兑付等服务。如果我向你提问，你只能选取本地知识库的政策内容回答，不要回复无关内容。";
  await streamFetch(prompt + "：" + message.value);
  message.value = '';
};

const streamFetch = async (msg) => {
  const response = await fetch(`/anythingllm/api/v1/workspace/${workspaceId.value}/thread/${threadId.value}/stream-chat`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer EQY2WJW-TZ34W1B-H1BENNW-FSVWPDM`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      "mode": "chat",
      "message": msg
    }),
  });
  const reader = response.body.getReader();
  const decoder = new TextDecoder();
  let done = false;
  let buffer = ''; // 用于存储未处理的部分消息
  output.value += '<div class="question">' + message.value.trim() + '</div>';
  message.value = '';
  while (!done) {
    const { value, done: streamDone } = await reader.read();
    done = streamDone;
    buffer += decoder.decode(value, { stream: true });
    buffer = buffer.startsWith("data:") ? buffer.slice(6).trim() : buffer.trim();
    console.log(buffer);
    try {
      // 尝试解析完整的 JSON 消息
      const jsonMessages = buffer.split('\n').filter(line => line.trim() !== '').map(line => line.replace(/^data: /, ''));
      for (const jsonMessage of jsonMessages) {
        const bufferJson = JSON.parse(jsonMessage);
        const tep_mesg = bufferJson?.textResponse || "";
        const tep_sources = bufferJson?.sources || [];
        if (tep_mesg === '<think>') {
          output.value += "<div class='think'>";
        } else if (tep_mesg === '</think>') {
          output.value += "</div>";
        } else {
          output.value += tep_mesg;
          if (tep_sources.length > 0) {
            output.value += "<div class='sources'>";
            tep_sources.forEach((source) => {
              output.value += "<a href='" + source.url + "' target='_blank'>" + source.title.replace(".txt", "") + "</a></br>";
            });
            output.value += "</div>";
          }
        }
      }
      buffer = ''; // 清空缓冲区
    } catch (error) {
      // 如果解析失败，保留缓冲区内容，等待下一次读取
      console.log("JSON parse error:", error);
    }
    chatDiv.value.innerHTML = marked.parse(output.value.trim(), { renderer: renderer.value, breaks: true, gfm: true });
    chatDiv.value.scrollTop = chatDiv.value.scrollHeight;
  }
};

const createThread = async (id) => {
  const response = await fetch(`/anythingllm/api/v1/workspace/${workspaceId.value}/thread/new`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer EQY2WJW-TZ34W1B-H1BENNW-FSVWPDM`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      "userId": null,
      "name": "",
      "slug": id
    }),
  });
  if (!response.ok) {
    threadId.value = null;
    throw new Error(`HTTP 错误！状态码：${response.status}`);
  }
  const data = await response.json();
  threadId.value = data.thread.slug;
  localStorage.setItem('current-thread', threadId.value);
};
</script>

<style scoped>
#chat-view {
  color: #333;
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.chat-header {
  padding: 10px;
  background-color: #007bff;
  color: #fff;
  text-align: center;
}

.chat-header h1 {
  margin: 0;
  font-size: 2em;
  padding-bottom: 5px;
}

.chat-header h2 {
  margin: 0;
  font-size: 1.1em;
  font-weight: normal;
}

.chat-body {
  display: flex;
  flex: 1;
  overflow: hidden;
}

.chat-container {
  display: flex;
  flex-direction: column;
  flex: 1;
  overflow: hidden;
  background-color: #fff;
  border-right: 1px solid #ddd;
}

.chat {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  background-color: #f9f9f9;
}

.input-container {
  display: flex;
  align-items: center;
  padding: 10px;
  background-color: #fff;
  border-top: 1px solid #ddd;
}

textarea {
  flex: 1;
  margin-right: 10px;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  resize: none;
  font-size: 1em;
}

button {
  padding: 10px 20px;
  border: none;
  background-color: #007bff;
  color: #fff;
  border-radius: 4px;
  cursor: pointer;
  font-size: 1em;
}

button:hover {
  background-color: #0056b3;
}

.chat-faq {
  width: 16vw;
  padding: 20px;
  background-color: #f5f5f5;
  overflow-y: auto;
}

.chat-faq h2 {
  margin-top: 0;
  font-size: 1.5em;
}

.chat-faq ul {
  list-style: none;
  padding: 0;
}

.chat-faq li {
  margin-bottom: 10px;
  cursor: pointer;
  color: #007bff;
  font-size: 1em;
}

.chat-faq li:hover {
  text-decoration: underline;
}

@media (max-width: 768px) {

  /* #chat-view {
    height: 98vh;
  } */

  .chat-faq {
    display: none;
    /* 在手机屏幕上隐藏 */
  }
}
</style>